import axios, { AxiosInstance, AxiosRequestConfig, AxiosPromise, AxiosResponse } from 'axios'
import config from '@/config';
const { api: { dev, pro } } = config;
const apiBaseUrl = process.env.NODE_ENV === 'production' ? dev : pro;

export interface ResponseData {
  code: number
  data?: any
  msg: string
}

//定义一个接口请求类，用于创建axios请求示例
class Request {
  
  constructor(public baseUrl: string = apiBaseUrl) {
    this.baseUrl = baseUrl
  } 

  //基础配置
  // getConfig():object{
  //   let config = {
  //     baseUrl: this.baseUrl
  //   }

  //   return config
  // }

  // 我们实际调用接口的时候调用实例的这个方法，他返回一个AxiosPromise
  public request(options: AxiosRequestConfig): AxiosPromise{
    // 这里使用axios.create方法创建一个axios实例，他是一个函数，同时这个函数包含多个属性
    const instance: AxiosInstance = axios.create()
    // 合并基础路径和每个接口单独传入的配置，比如url、参数等
    options = this.mergeConfig(options)
    //调用interceptors方法使拦截器生效
    this.interceptors(instance, options.url)
    //返回axiospromise
    return instance(options)
  }

  //添加全局拦截和响应请求
  private interceptors(instance: AxiosInstance, url?: string) {
    //请求拦截
    instance.interceptors.request.use((config: AxiosRequestConfig) => {
      // 接口请求的所有配置，都在这个config对象中，他的类型是AxiosRequestConfig，你可以看到他有哪些字段
      // 如果你要修改接口请求配置，需要修改 axios.defaults 上的字段值
      return config
    },
    (err) => { //报错回调
      return Promise.reject(err)
    })
    //响应拦截
    instance.interceptors.response.use((res:AxiosResponse) => {
      const { data } = res
      const { code, msg } = data
      if(code!==0){
        console.log(msg);
      }
      return res
    },
    (err) => {
      return Promise.reject(err)
    })
  }

  //用于合并基础路径配置和接口单独配置
  private mergeConfig(options: AxiosRequestConfig): AxiosRequestConfig{
    return Object.assign({baseUrl: this.baseUrl}, options)
  }
}

export default Request